package org.lwx.reflect;

import org.lwx.annotation.target.FIELD;
import org.lwx.annotation.target.SONTYPE;
import org.lwx.annotation.target.TYPE;

/**
 * @author lwx
 * @date 2020-09-18 16:20
 * @description
 **/
public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        Class<?> aClass = Class.forName("org.lwx.reflect.pojo.User");
         Class<?> aClass1 = Class.forName("org.lwx.reflect.pojo.User", false, ClassLoader.getSystemClassLoader());
         System.out.println(aClass);
         System.out.println(aClass1);
         System.out.println(aClass == aClass1);

        // 测试class上面的注解相关的内容,一共有8个.
        // getAnnotation可以获取到继承来的注解,如果要让注解变得可继承,需要使用元注解@Inherited
        // 注意,这种方式只在类继承上有效,在注解上加注解依然是获取不到的,实现接口也获取不到接口上的注解
        // 如果是这样的结构 User extends Father extend GrandFather, 注解标注在GrandFather上
        // 那么User的class依然可以获取到GrandFather上的注解
        // SONTYPE annotation = aClass.getAnnotation(SONTYPE.class);
        // TYPE annotation3 = aClass.getAnnotation(TYPE.class);
        // // getDeclaredAnnotation无法获取到继承来的注解,只能获取显示定义在类型上的注解
        // // 那这个注解就简洁明了多了,直接标注在上面的才有
        // SONTYPE declaredAnnotation = aClass.getDeclaredAnnotation(SONTYPE.class);
        // TYPE declaredAnnotation1 = aClass.getDeclaredAnnotation(TYPE.class);
        // // 判断这个类是否是一个注解
        // boolean annotation1 = aClass.isAnnotation();
        // boolean annotation2 = TYPE.class.isAnnotation();
        // // 假如这个类是一个注解,调用isInterface的返回结果也是true
        // // 因为所有的注解类型也都是接口类型
        // boolean anInterface = TYPE.class.isInterface();
        // // 获取全部注解,包括继承来的注解
        // Annotation[] getAnnotations = aClass.getAnnotations();
        // // 看清楚,返回值是不一样的,上面返回的是注解的抽象,这里返回的是具体的注解
        // // 那这里就需要搞清楚一个问题,究竟怎样算是同一个类型
        // TYPE[] getAnnotationsByType = aClass.getAnnotationsByType(TYPE.class);
        // SONTYPE[] getAnnotationsByType1 = aClass.getAnnotationsByType(SONTYPE.class);
        // // 获取全部标注在该类上的注解
        // Annotation[] getDeclaredAnnotations = aClass.getDeclaredAnnotations();
        // TYPE[] getDeclaredAnnotationsByType = aClass.getDeclaredAnnotationsByType(TYPE.class);
        // SONTYPE[] getDeclaredAnnotationsByType1 = aClass.getDeclaredAnnotationsByType(SONTYPE.class);
        /**
         * 判断某一个注解是否存在,这个挺实用的
         * 解释写的是真的好,因为等价于 clazz.getAnnotation(annotationClass) != null
         * 而这个方法可以拿到继承来的注解,so输入继承来的注解的class依然是返回true
         */
         boolean annotationPresent = aClass.isAnnotationPresent(TYPE.class);

        // 再来一遍,所有is的方法
        boolean isAnnotationPresent = aClass.isAnnotationPresent(SONTYPE.class);
        boolean isAnnotationPresent1 = aClass.isAnnotationPresent(FIELD.class);
        boolean annotation = aClass.isAnnotation();
        boolean anInterface = aClass.isInterface();
        // 普通类型
        boolean normalClass = aClass.isAnonymousClass();
        // lambda表达式
        Class<? extends Runnable> lambda = ((Runnable) () -> {
        }).getClass();
        boolean isLambda = lambda.isAnonymousClass();
        // 匿名内部类
        Class<? extends Runnable> anonymousClass = new Runnable() {
            @Override
            public void run() {
            }
        }.getClass();
        // 从结果可以看出 lambda并不是匿名内部类
        boolean isAnonymousClass = anonymousClass.isAnonymousClass();

        /**
         *  原来数组也属于一种特殊的类型
         */
        boolean array = String[].class.isArray();
        boolean array1 = String[][].class.isArray();

        /**
         * 检查是否是基本数据类型
         */
        boolean primitive = aClass.isPrimitive();
        boolean primitive1 = int.class.isPrimitive();
        boolean primitive2 = Integer.class.isPrimitive();

        // 好诡异..感觉越挖越深了...
        aClass.isSynthetic();

        System.out.println();
    }
}
